package com.lq.mode.singleton;

/**
 * @program: singleton-mode
 * @description: 懒汉单例模式双锁，基本完善
 * @author: LQ
 * @create: 2019-11-07 22:57
 * 单例模式
 */

public class SingletonMode4 {
    /**
     * 使用volatile关键字修饰的变量不会被线程本地缓存
     * 所有线程的对该对象的读写都会第一时间被保存到主内存
     * volatile的作用:
     * 防止指令重排:因为mode = new SingletonMode4()不是原子性的,可能声明了,有地址了,但是没有初始化
     * 保证内存可见
     */
    private volatile static SingletonMode4 mode = null;

    /**
     * 单例模式,构造方法私有化
     */
    private SingletonMode4() {
    }

    /**
     * 获取单例模式的对象,加了锁，线程安全了，但是空间换时间，效率低
     *
     * @return
     */
    public static SingletonMode4 getMode() {
        if (mode == null) {
            // 同步块,线程安全的创建实例
            // synchronized在内部,在调用的时候是不需要加锁的,只有为空的时候才加锁
            synchronized (SingletonMode4.class) {
                if (mode == null) {
                    mode = new SingletonMode4();
                }
            }
            mode = new SingletonMode4();
        }
        return mode;
    }
}
